﻿using BZ.Core.Frm;
using NDK.Motion.Card;
using NDK.Motion.MachineManager;
using NDK.Motion.MachineResources;
using NDK.Utils;
using HZH_Controls.Forms;
using LightController;
using LightController.Frm;
//using LightController.Frm;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Data;

namespace NDK.Motion.Frm
{
    public partial class Frm_MachineConfig : Form
    {
        private static log4net.ILog traceLogger = log4net.LogManager.GetLogger("Frm_MachineConfig");

        List<ICard> cardList = new List<ICard>();

        /// <summary>
        /// 窗体关闭状态
        /// </summary>
        public bool isFrmClosed = false;
        /// <summary>
        /// 初始化
        /// </summary>
        private Frm_MachineConfig()
        {
            InitializeComponent();
            //初始化空界面
            var tn = new TreeNode("Cards");
            tn.Name = "tn_Cards";
            tn.ImageIndex = 2;
            tn.SelectedImageIndex = 2;
            tv_Cards.Nodes.Add(tn);

            tn = new TreeNode("Cylinders");
            tn.Name = "tn_Cylinders";
            tn.ImageIndex = 3;
            tn.SelectedImageIndex = 3;
            tv_Cylinder.Nodes.Add(tn);

            tn = new TreeNode("DI");
            tn.Name = "tn_DI";
            tn.ImageIndex = 4;
            tn.SelectedImageIndex = 4;
            tv_IO.Nodes.Add(tn);

            tn = new TreeNode("DO");
            tn.Name = "tn_DO";
            tn.ImageIndex = 4;
            tn.SelectedImageIndex = 4;
            tv_IO.Nodes.Add(tn);

            //tn = new TreeNode("LightControllers");
            //tn.Name = "tn_LightSource";
            //tn.ImageIndex = 6;
            //tn.SelectedImageIndex = 6;
            //tv_LightController.Nodes.Add(tn);
            //初始化配置路径
            string dirConfig = Application.StartupPath + @"\Config\";
            if (!Directory.Exists(dirConfig))
            {
                Directory.CreateDirectory(dirConfig);
            }
        }
        #region 窗体对象实例，单例模式,保证整个工程只有一个实例
        private static Frm_MachineConfig _instance;
        private static readonly object singletonLock = new object();
        public static Frm_MachineConfig Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (singletonLock)
                    {
                        if (_instance == null)
                        {
                            _instance = new Frm_MachineConfig();
                        }
                    }
                }
                return _instance;
            }
        }
        #endregion

        /// <summary>
        /// 窗体加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Frm_MachineConfig_Load(object sender, EventArgs e)
        {
            //To Do:检测配置文件是否存在，如果存在直接读入，否则引导用户进行配置，或者拷贝配置文件到相应位置
            buttonItem_OpenMachineConfig_Click(null, null);
            backgroundWorker1.RunWorkerAsync();
            IniPosDataGridView();
        }

        /// <summary>
        /// 双击资源父节点，弹出配置框，配置结束添加到资源列表中
        /// 资源包括：Card,Axis,Cylinder
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tv_Resources_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Name == "tn_Cards")
            {
                Dlg_AddCard cardConfigDlg = new Dlg_AddCard();
                cardConfigDlg.Title = "Add Card";
                cardConfigDlg.StartPosition = FormStartPosition.CenterScreen;
                if (cardConfigDlg.ShowDialog() == DialogResult.OK)
                {
                    foreach (IMotionCard card in cardConfigDlg.MotionCards)
                    {

                        card.CardName = card.CardType + "_" + card.CardID;//给个默认名称
                        //将该卡添加到资源管理列表
                        try
                        {
                            if (MachineDataManager.Instance.AddCard(card))
                            {
                                //将该卡添加界面列表
                                var tn_Parent = new TreeNode(card.CardType + "(" + card.CardID + ")");
                                tn_Parent.Name = "tn_" + card.CardType + "_" + card.CardID;
                                tn_Parent.ImageIndex = 2;
                                tn_Parent.SelectedImageIndex = 2;
                                tn_Parent.Tag = card;
                                //将轴加到卡下
                                for (int axisID = card.StartAxisID; axisID < card.TotalAxis + card.StartAxisID; axisID++)
                                {
                                    string defaultAxisName = card.CardName + ": Axis" + axisID;//轴的默认名称
                                    Axis axis = new Axis()
                                    {
                                        Name = defaultAxisName,
                                        AxisID = axisID,
                                        Card = card,
                                        Type = AXIS_TYPE.X
                                    };
                                    if (MachineDataManager.Instance.AddAxis(axis))
                                    {
                                        var tn_Child = new TreeNode(defaultAxisName);
                                        tn_Child.Name = "tn_" + defaultAxisName;
                                        tn_Child.ImageIndex = 0;
                                        tn_Child.SelectedImageIndex = 0;
                                        tn_Child.Tag = axis;
                                        tn_Parent.Nodes.Add(tn_Child);
                                    }
                                }
                                e.Node.Nodes.Add(tn_Parent);

                                //将DO加到IO下
                                if (card.OutputCount > 0)
                                {
                                    var tn_Parent_Out = new TreeNode(card.CardType + "(" + card.CardID + ")");
                                    tn_Parent_Out.Name = "tn_" + card.CardType + "_" + card.CardID;
                                    tn_Parent_Out.ImageIndex = 4;
                                    tn_Parent_Out.SelectedImageIndex = 41;
                                    tn_Parent.Tag = card;
                                    for (int port = 0; port < card.OutputCount; port++)
                                    {
                                        string defaultDOName = "DO" + port + "(" + card.CardID + ")";//默认名称
                                        OutputSetting outputModel = new OutputSetting(defaultDOName, card, port);
                                        if (MachineDataManager.Instance.AddDO(outputModel))
                                        {
                                            //var tn_Child = new TreeNode(defaultDOName);
                                            //tn_Child.Name = "tn_" + defaultDOName;
                                            //tn_Child.ImageIndex = 4;
                                            //tn_Child.SelectedImageIndex = 4;
                                            //tn_Parent_Out.Nodes.Add(tn_Child);
                                        }
                                    }
                                    tv_IO.Nodes[1].Nodes.Add(tn_Parent_Out);

                                }

                                //将DI加到IO下
                                if (card.InputCount > 0)
                                {
                                    var tn_Parent_In = new TreeNode(card.CardType + "(" + card.CardID + ")");
                                    tn_Parent_In.Name = "tn_" + card.CardType + "_" + card.CardID;
                                    tn_Parent_In.ImageIndex = 4;
                                    tn_Parent_In.SelectedImageIndex = 4;
                                    tn_Parent.Tag = card;
                                    for (int port = 0; port < card.InputCount; port++)
                                    {
                                        string defaultName = "DI" + port + "(" + card.CardID + ")";//默认名称
                                        InputSetting inputModel = new InputSetting(defaultName, card, port);
                                        if (MachineDataManager.Instance.AddDI(inputModel))
                                        {
                                            //var tn_Child = new TreeNode(defaultName);
                                            //tn_Child.Name = "tn_" + defaultName;
                                            //tn_Child.ImageIndex = 4;
                                            //tn_Child.SelectedImageIndex = 4;
                                            //tn_Parent_In.Nodes.Add(tn_Child);
                                        }
                                    }
                                    tv_IO.Nodes[0].Nodes.Add(tn_Parent_In);
                                }

                            }
                        }
                        catch (Exception ex)
                        {
                            traceLogger.Error(ex.StackTrace);
                        }
                        e.Node.Expand();
                    }
                    foreach (ICard card in cardConfigDlg.IOCards)
                    {
                        card.CardName = card.CardType + "_" + card.CardID;//给个默认名称
                        if (MachineDataManager.Instance.AddCard(card))
                        {
                            //将该卡添加界面列表
                            var tn_Parent = new TreeNode(card.CardType + "(" + card.CardID + ")");
                            tn_Parent.Name = "tn_" + card.CardType + "_" + card.CardID;
                            tn_Parent.ImageIndex = 2;
                            tn_Parent.SelectedImageIndex = 2;
                            e.Node.Nodes.Add(tn_Parent);
                            //将DO加到IO下
                            tn_Parent = new TreeNode(card.CardType + "(" + card.CardID + ")");
                            tn_Parent.Name = "tn_" + card.CardType + "_" + card.CardID;
                            tn_Parent.ImageIndex = 4;
                            tn_Parent.SelectedImageIndex = 4;
                            for (int port = 0; port < card.OutputCount; port++)
                            {
                                string defaultDOName = "DO" + port + "(" + card.CardType + "_" + card.CardID + ")";//默认名称
                                OutputSetting outputModel = new OutputSetting(defaultDOName, card, port);
                                if (MachineDataManager.Instance.AddDO(outputModel))
                                {
                                    //var tn_Child = new TreeNode(defaultDOName);
                                    //tn_Child.Name = "tn_" + defaultDOName;
                                    //tn_Child.ImageIndex = 4;
                                    //tn_Child.SelectedImageIndex = 4;
                                    //tn_Parent.Nodes.Add(tn_Child);
                                }
                            }
                            tv_IO.Nodes[1].Nodes.Add(tn_Parent);
                            //将DI加到IO下
                            tn_Parent = new TreeNode(card.CardType + "(" + card.CardID + ")");
                            tn_Parent.Name = "tn_" + card.CardType + "_" + card.CardID;
                            tn_Parent.ImageIndex = 4;
                            tn_Parent.SelectedImageIndex = 4;
                            for (int port = 0; port < card.InputCount; port++)
                            {
                                string defaultName = "DI" + port + "(" + card.CardType + "_" + card.CardID + ")";//默认名称
                                InputSetting inputModel = new InputSetting(defaultName, card, port);
                                if (MachineDataManager.Instance.AddDI(inputModel))
                                {
                                    //var tn_Child = new TreeNode(defaultName);
                                    //tn_Child.Name = "tn_" + defaultName;
                                    //tn_Child.ImageIndex = 4;
                                    //tn_Child.SelectedImageIndex = 4;
                                    //tn_Parent.Nodes.Add(tn_Child);
                                }
                            }
                            tv_IO.Nodes[0].Nodes.Add(tn_Parent);
                        }
                    }
                }
            }
            if (e.Node.Tag is Axis)
            {
                MinimizeMdiForm();

                Frm_MotionConfig motionConfigForm = Frm_MotionConfig.Instance;
                motionConfigForm.MdiParent = this;
                this.p_ConfigContainer.Controls.Add(motionConfigForm);
                motionConfigForm.Show();

            }
            if (e.Node.Tag is ICard)
            {
                MinimizeMdiForm();

                ICard card = ((ICard)(e.Node.Tag));
                Dlg_CardDebug dlg_CardDebug = Dlg_CardDebug.Instance;
                dlg_CardDebug.Text = card.CardName;
                dlg_CardDebug.MdiParent = this;
                this.p_ConfigContainer.Controls.Add(dlg_CardDebug);
                dlg_CardDebug.Show();
            }
        }

        /// <summary>
        /// 最小化当前MDI父窗体中的子窗体
        /// </summary>
        private void MinimizeMdiForm()
        {
            foreach (Control ctrl in this.p_ConfigContainer.Controls)
            {
                if (ctrl is Form)
                {
                    Form form = ctrl as Form;
                    form.WindowState = FormWindowState.Minimized;
                }
            }
        }

        /// <summary>
        /// 右击轴，弹出轴调试窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tv_Resources_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if ((e.Button == MouseButtons.Right))
            {
                if (e.Node.Tag is Axis)
                {
                    try
                    {
                        Axis axis = MachineDataManager.Instance.GetAxis(e.Node.Text);
                        Dlg_AxisDebug axisConfigDlg = new Dlg_AxisDebug();
                        axisConfigDlg.Axis = axis;
                        axisConfigDlg.AxisId = axis.AxisID;
                        axisConfigDlg.AxisName = e.Node.Text;
                        axisConfigDlg.StartPosition = FormStartPosition.CenterScreen;
                        axisConfigDlg.Show();
                    }
                    catch (Exception ex)
                    {
                        traceLogger.Error(ex.StackTrace);
                    }
                }
            }
            if ((e.Button == MouseButtons.Right))
            {
                if (e.Node.Tag is ICard)
                {
                    Dlg_Confirm dlg_Confirm = new Dlg_Confirm("提示", $"确定删除{((ICard)(e.Node.Tag)).CardName}");
                    if (dlg_Confirm.ShowDialog() == DialogResult.OK)
                    {
                        MachineDataManager.Instance.RemoveCard((ICard)(e.Node.Tag));
                        ReloadProject();
                    }
                }
            }
        }

        private void IniPosDataGridView()
        {
            MachineDataManager.Instance.LocalPostion = new Dictionary<string, DataTable>();
            DataTable dt;
            foreach (Station item in MachineDataManager.Instance.StationList)
            {
                dt = new DataTable();
                dt.Columns.Add("Guid", Type.GetType("System.String"));
                dt.Columns.Add("点位名称", Type.GetType("System.String"));
                dt.Columns.Add("执行顺序", Type.GetType("System.UInt32"));
                dt.Columns.Add("轴优先级", Type.GetType("System.UInt32"));

                foreach (var axis in item.AxisList)
                {
                    dt.Columns.Add(axis.Name, Type.GetType("System.Double"));
                }
                dt.Columns.Add("功能类型", Type.GetType("System.String"));
                dt.Columns.Add("点位描述", Type.GetType("System.String"));
                dt.Columns.Add("是否执行", Type.GetType("System.Boolean"));
                dt.Columns.Add("是否统一设定", Type.GetType("System.Boolean"));
                dt.Columns.Add("工站", Type.GetType("System.String"));

                //重新绑定当前选中工站的点位表（如果本地没有该工位的点位表，则生成一个，否则从本地读出来显示到界面）

                if (!MachineDataManager.Instance.IsExistPositionTable(item.StationName))
                {
                    MachineDataManager.Instance.SavePositionTable(dt, item.StationName);
                }
                else
                {
                    dt = MachineDataManager.Instance.LoadPositionTable(item.StationName);
                }
                MachineDataManager.Instance.LocalPostion.Add(item.StationName, dt);
            }
        }


        /// <summary>
        /// 保存当前配置到指定路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonItem_Save_Click(object sender, EventArgs e)
        {
            MachineDataManager.SaveToFile();
            FrmTips.ShowTipsSuccess(this, "保存成功！");
        }

        /// <summary>
        /// 加载项目配置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonItem_OpenMachineConfig_Click(object sender, EventArgs e)
        {
            try
            {
                if (MachineDataManager.Instance.CardList.Count == 0)
                {
                    // MachineDataManager.LoadFromFile();
                }

                #region Card
                //Card
                tv_Cards.Nodes.Clear();
                tv_Cards.ImageIndex = 2;
                var tn = new TreeNode("Cards");
                tn.Name = "tn_Cards";
                tn.ImageIndex = 2;
                tn.SelectedImageIndex = 2;
                tv_Cards.Nodes.Add(tn);
                foreach (ICard card in MachineDataManager.Instance.CardList)
                {
                    if (card == null)
                    {
                        continue;
                    }
                    var tn_Card = new TreeNode(card.CardName);
                    tn_Card.ImageIndex = 2;
                    tn_Card.SelectedImageIndex = 2;
                    tn_Card.Tag = card;
                    tn.Nodes.Add(tn_Card);

                    if (card.Initialized == false)
                    {
                        try
                        {
                            card.CardInit(0);
                        }
                        catch (Exception ex)
                        {
                            traceLogger.Error(ex.Message);
                        }
                    }

                    foreach (var axis in MachineDataManager.Instance.AxisList)
                    {
                        if (axis.Card.CardID == card.CardID && axis.Card.CardType == card.CardType)
                        {
                            axis.Card = (IMotionCard)card;
                            var tn_Child = new TreeNode(axis.Name);
                            tn_Child.ImageIndex = 0;
                            tn_Child.SelectedImageIndex = 0;

                            bool isAlm = true;
                            bool isServoOn = false;
                            if (axis.Card?.Initialized == true)
                            {
                                isAlm = axis.GetAlarm();
                                isServoOn = axis.GetServoOn();
                            }
                            if (isAlm == false && isServoOn == false)
                            {
                                tn_Child.ImageIndex = 1;
                                tn_Child.SelectedImageIndex = 1;
                            }
                            else if (isAlm == true)
                            {
                                tn_Child.ImageIndex = 5;
                                tn_Child.SelectedImageIndex = 5;
                            }

                            tn_Child.Name = "tn_Axis" + axis.AxisID;
                            tn_Child.Tag = axis;
                            tn_Card.Nodes.Add(tn_Child);
                        }
                    }
                }
                tv_Cards.ExpandAll();
                #endregion

                #region Cylinder
                //Cylinder
                tv_Cylinder.Nodes.Clear();
                tn = new TreeNode("Cylinders");
                tn.Name = "tn_Cylinders";
                tn.ImageIndex = 3;
                tn.SelectedImageIndex = 3;
                tv_Cylinder.Nodes.Add(tn);
                foreach (var cylinder in MachineDataManager.Instance.CylinderList)
                {
                    var tn_Cylinder = new TreeNode(cylinder.Name);
                    tn_Cylinder.Name = "tn_" + cylinder.Name;
                    tn_Cylinder.ImageIndex = 3;
                    tn_Cylinder.SelectedImageIndex = 3;
                    tn_Cylinder.Tag = cylinder;
                    tn.Nodes.Add(tn_Cylinder);
                }
                #endregion

                #region IO
                //DI
                tv_IO.Nodes.Clear();
                tn = new TreeNode("DI");
                tn.Name = "tn_DI";
                tn.ImageIndex = 4;
                tn.SelectedImageIndex = 4;
                tv_IO.Nodes.Add(tn);

                foreach (var card in MachineDataManager.Instance.CardList)
                {
                    var tn_Card = new TreeNode(card.CardType + "(" + card.CardID + ")");
                    tn_Card.Name = "tn_" + card.CardType + "_" + card.CardID;
                    tn.Nodes.Add(tn_Card);

                    //foreach (InputSetting inputModel in MachineDataManager.Instance.DIList)
                    //{
                    //    if (inputModel.Card != null)
                    //    {
                    //        if (inputModel.Card.CardID == card.CardID && inputModel.Card.CardType == card.CardType)
                    //        {
                    //            var tn_DI = new TreeNode(inputModel.Name);
                    //            tn_DI.ImageIndex = 0;
                    //            tn_DI.SelectedImageIndex = 0;
                    //            tn_Card.Nodes.Add(tn_DI);
                    //        }
                    //    }

                    //}
                }

                //DO
                tn = new TreeNode("DO");
                tn.Name = "tn_DO";
                tn.ImageIndex = 4;
                tv_IO.Nodes.Add(tn);
                foreach (var card in MachineDataManager.Instance.CardList)
                {
                    var tn_Card = new TreeNode(card.CardType + "(" + card.CardID + ")");
                    tn_Card.Name = "tn_" + card.CardType + "_" + card.CardID;
                    tn.Nodes.Add(tn_Card);

                    //foreach (OutputSetting outputModel in MachineDataManager.Instance.DOList)
                    //{
                    //    if (outputModel.Card.CardID == card.CardID && outputModel.Card.CardType == card.CardType)
                    //    {
                    //        var tn_DO = new TreeNode(outputModel.Name);
                    //        tn_DO.ImageIndex = 0;
                    //        tn_DO.SelectedImageIndex = 0;
                    //        if (outputModel.Card?.Initialized == false)
                    //        {
                    //            tn_DO.ImageIndex = 5;
                    //            tn_DO.SelectedImageIndex = 5;
                    //        }

                    //        tn_Card.Nodes.Add(tn_DO);
                    //    }
                    //}



                }
                #endregion

                #region LightController 
                //LightController
                if (MachineDataManager.Instance.LightControllerList != null)
                {
                    tv_LightController.Nodes.Clear();
                    foreach (var lightController in MachineDataManager.Instance.LightControllerList)
                    {
                        if (lightController.ID == null)
                        {
                        reget:
                            var id = Guid.NewGuid().ToString();
                            var Controller = MachineDataManager.Instance.LightControllerList.FindAll(x => x.ID == id);
                            if (Controller.Count > 0)
                                goto reget;
                            else
                                lightController.ID = id;
                        }

                        string nodeName = lightController.Name + "(" + lightController.CommunicationAddress + ")";
                        var tn_lightController = new TreeNode(nodeName);
                        tn_lightController.Name = nodeName;
                        tn_lightController.Tag = lightController;
                        tv_LightController.Nodes.Add(tn_lightController);

                        foreach (var ch in lightController.ChanelList)
                        {
                            var tn1 = new TreeNode(ch.Name);
                            tn1.Name = ch.Name;
                            tn1.Tag = ch;
                            tn_lightController.Nodes.Add(tn1);
                        }
                    }
                }
                #endregion

            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
                FrmTips.ShowTipsError(this, "加载异常！" + ex.Message);

            }

            FrmTips.ShowTipsSuccess(this, "加载成功！");
        }
        public void ReloadProject()
        {
            buttonItem_OpenMachineConfig_Click(null, null);
        }
        /// <summary>
        /// 轴名称修改，节点上修改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tv_Cards_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            //e.CancelEdit = true;
            //return;
            if (e.Node.Tag is Axis)
            {
                try
                {
                    //获取编辑的节点名称
                    string oldName = tv_Cards.SelectedNode.Text;
                    //获取修改后的新名称,没有修改或则名称为空字符串则返回
                    if (e.Label == string.Empty || e.Label == null)
                    {
                        e.CancelEdit = true;
                        return;
                    }

                    string newName = e.Label != "NULL" ? e.Label : oldName;
                    if (oldName == newName) return;
                    Axis axis1 = (Axis)(e.Node.Tag); ;
                    Axis axis = MachineDataManager.Instance.AxisList.Find(c => c.Name == oldName && c.AxisID == axis1.AxisID && c.Card.CardName == axis1.Card.CardName);
                    if (axis == null) return;
                    axis.Name = newName;
                }
                catch (Exception ex)
                {
                    traceLogger.Error(ex.StackTrace);
                }
            }
        }

        /// <summary>
        /// 双击IO节点，弹出IO表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tv_IO_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (e.Node.Name == "tn_DI")
                {
                    try
                    {
                        MinimizeMdiForm();
                        Frm_DI diForm = Frm_DI.Instance;
                        diForm.MdiParent = this;
                        this.p_ConfigContainer.Controls.Add(diForm);
                        diForm.Show();
                    }
                    catch (Exception ex)
                    {
                        traceLogger.Error(ex.StackTrace);
                    }

                }
                if (e.Node.Name == "tn_DO")
                {
                    try
                    {
                        MinimizeMdiForm();
                        Frm_DO doForm = Frm_DO.Instance;
                        doForm.MdiParent = this;
                        this.p_ConfigContainer.Controls.Add(doForm);
                        doForm.Show();
                    }
                    catch (Exception ex)
                    {
                        traceLogger.Error(ex.StackTrace);
                    }
                }
            }
        }

        /// <summary>
        /// 单击气缸节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tv_Cylinder_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (e.Node?.Tag is ICylinder)
                {
                    ICylinder cylinderTag = (ICylinder)e.Node?.Tag;
                    if (cylinderTag == null)
                    {
                        return;
                    }
                    ICylinder cylinder = MachineDataManager.Instance.CylinderList.Find(l => l.Name == cylinderTag.Name);
                    if (cylinder == null)
                    {
                        return;
                    }
                    Dlg_Confirm dlg_Confirm = new Dlg_Confirm("确认框", $"确定删除{cylinder.Name}");
                    if (dlg_Confirm.ShowDialog() == DialogResult.OK)
                    {
                        MachineDataManager.Instance.CylinderList.Remove(cylinder);
                        MachineDataManager.SaveToFile();
                        ReloadProject();
                    }
                }
            }
        }
        /// <summary>
        /// 双击气缸节点，弹出气缸配置界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tv_Cylinder_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                try
                {
                    MinimizeMdiForm();
                    Frm_Cylinder cylinderFrm = Frm_Cylinder.Instance;
                    cylinderFrm.MdiParent = this;
                    this.p_ConfigContainer.Controls.Add(cylinderFrm);
                    cylinderFrm.Show();
                }
                catch (Exception ex)
                {
                    traceLogger.Error(ex.StackTrace);
                }
            }
        }

        /// <summary>
        /// Machine.cs文件生成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonItem_CodeGenerate_Click(object sender, EventArgs e)
        {
            try
            {
                if (MessageBox.Show(this, "确定根据当前配置生成资源类吗？" + Environment.NewLine + @"点击确定将生成到[D:\代码生成\]目录下！", "确认框", MessageBoxButtons.OKCancel) == DialogResult.OK)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("using  NDK.Motion.MachineResources;");
                    sb.AppendLine("using  System.Linq;");
                    sb.AppendLine(Environment.NewLine);
                    sb.AppendLine("namespace  NDK.Motion.BLL");
                    sb.AppendLine("{");

                    sb.AppendLine("    public static class Machine");
                    sb.AppendLine("    {");
                    //DI
                    sb.AppendLine(@"       //DI");
                    foreach (var diModel in MachineDataManager.Instance.DIList)
                    {
                        sb.AppendLine("       public static InputModel di_" + diModel.Name.Replace("(", "_").Replace(")", "") + " = MachineDataManager.Instance.DIList.SingleOrDefault(d => d.Name == \"" + diModel.Name + "\");");
                    }
                    sb.AppendLine(Environment.NewLine);
                    //DO
                    sb.AppendLine(@"       //DO");
                    foreach (var doModel in MachineDataManager.Instance.DOList)
                    {
                        sb.AppendLine("       public static OutputModel do_" + doModel.Name.Replace("(", "_").Replace(")", "") + " = MachineDataManager.Instance.DOList.SingleOrDefault(d => d.Name == \"" + doModel.Name + "\");");
                    }
                    sb.AppendLine(Environment.NewLine);
                    //Cylinder
                    sb.AppendLine(@"       //Cylinder");
                    foreach (var cylinderModel in MachineDataManager.Instance.CylinderList)
                    {
                        sb.AppendLine("       public static ICylinder cylinder_" + cylinderModel.Name + " = MachineDataManager.Instance.CylinderList.SingleOrDefault(d => d.Name == \"" + cylinderModel.Name + "\");");
                    }
                    sb.AppendLine(Environment.NewLine);
                    //Axis
                    sb.AppendLine(@"       //Axis");
                    foreach (var axisModel in MachineDataManager.Instance.AxisList)
                    {
                        sb.AppendLine("       public static Axis axis_" + axisModel.Name + " = MachineDataManager.Instance.AxisList.SingleOrDefault(d => d.AxisName == \"" + axisModel.Name + "\");");
                    }
                    sb.AppendLine(Environment.NewLine);
                    //点位
                    //sb.AppendLine(@"       //点位");
                    //foreach (var posModel in MachineDataManager.Instance.PositionList)
                    //{
                    //    sb.AppendLine("       public static Position pos_" + posModel.PositionName + "_" + posModel.Station + " = MachineDataManager.Instance.PositionList.SingleOrDefault(d => d.PositionName == \"" + posModel.PositionName + "\" && d.Station == \"" + posModel.Station + "\");");
                    //}
                    //sb.AppendLine(Environment.NewLine);



                    sb.AppendLine(@"        /// <summary>
        /// 检查所有资源是否读取到
        /// </summary>
        /// <returns></returns>");
                    sb.AppendLine("        public static string Check()");
                    sb.AppendLine("        {");
                    sb.AppendLine(@"            string errMsg = """";");
                    sb.AppendLine(@"            //DI检测");
                    foreach (var diModel in MachineDataManager.Instance.DIList)
                    {
                        sb.AppendLine(@"            if (di_" + diModel.Name.Replace("(", "_").Replace(")", "") + " == null) errMsg += \"" + diModel.Name + ",\";");
                    }
                    sb.AppendLine(@"            //DO检测");
                    foreach (var doModel in MachineDataManager.Instance.DOList)
                    {
                        sb.AppendLine(@"            if (do_" + doModel.Name.Replace("(", "_").Replace(")", "") + " == null) errMsg += \"" + doModel.Name + ",\";");
                    }
                    sb.AppendLine(@"            //Axis检测");
                    foreach (var axis in MachineDataManager.Instance.AxisList)
                    {
                        sb.AppendLine(@"            if (axis_" + axis.Name + " == null) errMsg += \"" + axis.Name + ",\";");
                    }
                    sb.AppendLine(@"            //Cylinder检测");
                    foreach (var cylinder in MachineDataManager.Instance.CylinderList)
                    {
                        sb.AppendLine(@"            if (cylinder_" + cylinder.Name + " == null) errMsg += \"" + cylinder.Name + ",\";");
                    }
                    //sb.AppendLine(@"            //点位");
                    //foreach (var posModel in MachineDataManager.Instance.PositionList)
                    //{
                    //    sb.AppendLine(@"            if (pos_" + posModel.PositionName + "_" + posModel.Station + " == null) errMsg += \"" + posModel.PositionName + "_" + posModel.Station + ",\";");
                    //}

                    sb.AppendLine("            return errMsg;");
                    sb.AppendLine("        }");



                    sb.AppendLine(@"        /// <summary>
        /// 点位轴绑定
        /// </summary>
        /// <returns></returns>");
                    //sb.AppendLine("        public static void BindAxis()");
                    //sb.AppendLine("        {");
                    //foreach (var posModel in MachineDataManager.Instance.PositionList)
                    //{
                    //    sb.AppendLine(@"            pos_" + posModel.PositionName + "_" + posModel.Station + ".AxisList = MachineDataManager.Instance.AxisList;");
                    //}
                    //sb.AppendLine("        }");


                    //sb.AppendLine("    }");
                    //sb.AppendLine("}");

                    string dir = @"D:/代码生成";
                    string strPath = dir + @"/Machine.cs";

                    string str = sb.ToString();

                    if (!Directory.Exists(dir))
                    {
                        Directory.CreateDirectory(dir);
                    }
                    FileUtils.WriteText(strPath, str, Encoding.UTF8);
                }
            }
            catch (Exception ex)
            {
                traceLogger.Error(ex.StackTrace);
            }
        }

        private void buttonItem_Clear_Click(object sender, EventArgs e)
        {
            Dlg_Confirm confirmDlg = new Dlg_Confirm("确认框", "确认清除项目文件吗？");
            if (confirmDlg.ShowDialog(this) == DialogResult.OK)
            {
                MachineDataManager.Instance.ClearFile();
            }
        }

        private void Frm_MachineConfig_FormClosing(object sender, FormClosingEventArgs e)
        {
            _instance = null;
            isFrmClosed = true;
            foreach (var frm in this.p_ConfigContainer.Controls)//释放子窗体
            {
                if (frm is Form)
                {
                    ((Form)frm).Close();
                }
            }
            //this.Hide();
            //e.Cancel = true;
        }

        private void bi_AxisStatus_Click(object sender, EventArgs e)
        {
            Frm_AxisStatus.Instance.Show();
        }

        private void bi_SysIO_Click(object sender, EventArgs e)
        {
            Dlg_SysIOConfig dlg_SysIOConfig = new Dlg_SysIOConfig();
            dlg_SysIOConfig.ShowDialog();

        }

        //监控轴状态
        private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            while (isFrmClosed == false)
            {
                Thread.Sleep(100);
                Application.DoEvents();

                foreach (TreeNode tv_Child in tv_Cards.Nodes)//root
                    foreach (TreeNode tn_Card in tv_Child.Nodes)//遍历卡
                        foreach (TreeNode tn_Child in tn_Card.Nodes)//遍历轴
                        {
                            if (tn_Child.Name.Contains("Axis"))
                            {
                                Axis axis = (Axis)(tn_Child.Tag);
                                if (axis?.Card?.Initialized == true)
                                {
                                    bool isAlm = true;
                                    bool isServoOn = false;
                                    if (axis.Card?.Initialized == true)
                                    {
                                        isAlm = axis.GetAlarm();
                                        isServoOn = axis.GetServoOn();
                                    }
                                    if (isAlm == false && isServoOn == false)
                                    {
                                        if (tn_Child.ImageIndex != 1)
                                        {
                                            tn_Child.ImageIndex = 1;
                                            tn_Child.SelectedImageIndex = 1;
                                        }
                                    }
                                    else if (isAlm == true)
                                    {
                                        if (tn_Child.ImageIndex != 5)
                                        {
                                            tn_Child.ImageIndex = 5;
                                            tn_Child.SelectedImageIndex = 5;
                                        }
                                    }
                                    else
                                    {
                                        if (tn_Child.ImageIndex != 0)
                                        {
                                            tn_Child.ImageIndex = 0;
                                            tn_Child.SelectedImageIndex = 0;
                                        }
                                    }
                                }
                            }
                        }
            }

        }

        #region 屏蔽双击节点，自动展开和自动收起的事件
        int nodeClicks = 0;
        TreeViewHitTestInfo treeViewHitTestInfo = null;
        private void tv_Cards_MouseDown(object sender, MouseEventArgs e)
        {
            var source = (TreeView)sender;
            treeViewHitTestInfo = source.HitTest(e.Location);
            nodeClicks = e.Clicks;
        }

        private void tv_Cards_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            if (nodeClicks > 1 && treeViewHitTestInfo.Location == TreeViewHitTestLocations.Label)
            {
                e.Cancel = true;
            }
        }

        private void tv_Cards_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            if (nodeClicks > 1 && treeViewHitTestInfo.Location == TreeViewHitTestLocations.Label)
            {
                e.Cancel = true;
            }
        }

        private void tsmi_AddLightController_Click(object sender, EventArgs e)
        {
            Dlg_AddLightController dlg_AddLightController = new Dlg_AddLightController();
            dlg_AddLightController.StartPosition = FormStartPosition.CenterScreen;
            if (dlg_AddLightController.ShowDialog() == DialogResult.OK)
            {
                ILightController lightController = dlg_AddLightController.LightController;
                if (MachineDataManager.Instance.LightControllerList == null)
                {
                    MachineDataManager.Instance.LightControllerList = new List<ILightController>();
                }
                var t = MachineDataManager.Instance.LightControllerList.FindAll(l => l.Name == lightController.Name);
                if (t == null || t.Count == 0)//没有相同名字的才能加入
                {
                    MachineDataManager.Instance.LightControllerList.Add(lightController);
                    foreach (var item in lightController.ChanelList)
                    {
                        MachineDataManager.Instance.LightList.Add(new Light() { LightController = lightController, Name = item.Name, LightChanel = new LightChanel() { Name = item.Name, No = item.No } });
                    }
                }
                else
                {
                    MessageBox.Show(lightController.Name + "已经存在!");
                    return;
                }

                string nodeName = lightController.Name + "(" + lightController.CommunicationAddress + ")";
                var tn = new TreeNode(nodeName);
                tn.Name = nodeName;
                tn.Tag = lightController;
                //tn.ImageIndex = 2;
                //tn.SelectedImageIndex = 2;
                tv_LightController.Nodes.Add(tn);

                foreach (var lightChanel in lightController.ChanelList)
                {
                    var tn1 = new TreeNode(lightChanel.Name);
                    tn1.Name = lightChanel.Name;
                    tn1.Tag = lightChanel;
                    tn.Nodes.Add(tn1);
                }
            }
        }

        private void tv_LightController_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            //if (e.Button == MouseButtons.Right)
            if (e.Node?.Tag is ILightController)
            {
                ILightController lightController1 = (ILightController)e.Node?.Tag;
                if (lightController1 == null)
                {
                    return;
                }
                {
                    ILightController lightController = MachineDataManager.Instance.LightControllerList.Find(l => l.Name == lightController1.Name);
                    if (lightController == null)
                    {
                        return;
                    }

                    Dlg_LightControllerDebug dlg_LightControllerDebug = new Dlg_LightControllerDebug();
                    dlg_LightControllerDebug.StartPosition = FormStartPosition.CenterScreen;
                    dlg_LightControllerDebug.LightController = lightController;
                    if (dlg_LightControllerDebug.ShowDialog() == DialogResult.OK)
                    {
                        lightController.ChanelCount = dlg_LightControllerDebug.Chs;
                        lightController.Name = dlg_LightControllerDebug.ControllerName;
                        lightController.CommunicationAddress = dlg_LightControllerDebug.ComAddress;

                        MachineDataManager.SaveToFile();
                    }
                }
            }
        }

        private void tv_LightController_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (e.Node?.Tag is ILightController)
                {
                    ILightController lightController1 = (ILightController)e.Node?.Tag;
                    if (lightController1 == null)
                    {
                        return;
                    }
                    ILightController lightController = MachineDataManager.Instance.LightControllerList.Find(l => l.Name == lightController1.Name);
                    if (lightController == null)
                    {
                        return;
                    }

                    Dlg_Confirm dlg_Confirm = new Dlg_Confirm("确认框", $"确定删除{lightController.Name}:{lightController.CommunicationAddress}");
                    if (dlg_Confirm.ShowDialog() == DialogResult.OK)
                    {
                        MachineDataManager.Instance.LightControllerList.Remove(lightController);

                        List<Light> DelLight = MachineDataManager.Instance.LightList.FindAll(l => l.LightControllerName == lightController.Name);
                        if (DelLight.Count > 0)
                        {
                            //foreach (var item in DelLight)
                            //{
                            //    MachineDataManager.Instance.LightList.Remove(item);
                            //}

                            MachineDataManager.Instance.LightList.RemoveAll(data => DelLight.Contains(data));
                        }

                        MachineDataManager.SaveToFile();
                        ReloadProject();
                    }
                }
            }
            else
            {

            }
        }

        private void tsmi_LightRecipe_Click(object sender, EventArgs e)
        {
            //MinimizeMdiForm();
            //Frm_LightRecipe frm_LightRecipe = Frm_LightRecipe.Instance;
            Frm_LightRecipe.Instance.TopLevel = true;
            Frm_LightRecipe.Instance.TopMost = true;
            Frm_LightRecipe.Instance.StartPosition = FormStartPosition.CenterScreen;
            Frm_LightRecipe.Instance.Show();
        }

        private void tv_LightController_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (e.Node?.Tag is LightChanel)
            {
                try
                {
                    //获取编辑的节点名称
                    string oldName = tv_LightController.SelectedNode.Text;
                    var parentNode = tv_LightController.SelectedNode.Parent;


                    //获取修改后的新名称,没有修改或则名称为空字符串则返回
                    if (e.Label == string.Empty || e.Label == null)
                    {
                        e.Node.Text = "";
                        e.CancelEdit = true;
                        return;
                    }
                    string newName = e.Label != "NULL" ? e.Label : oldName;

                    ILightController l1 = (ILightController)(parentNode.Tag);
                    LightChanel ch1 = (LightChanel)(e.Node.Tag);
                    ILightController l = MachineDataManager.Instance.LightControllerList.Find(c => c.CommunicationAddress == l1.CommunicationAddress);
                    LightChanel ch = l.ChanelList.Find(c => c.No == ch1.No);
                    if (l == null || ch == null) return;
                    if (ch.Name != oldName)
                    {
                        ch.Name = oldName;
                    }
                    var findLight = MachineDataManager.Instance.LightList.Find(x => x.LightController == l && x.LightChanel.No.Equals(ch.No));
                    if (findLight != null)
                    {
                        findLight.Name = newName;
                        ch.Name = newName;
                    }

                    //ReloadProject();
                    //tv_LightController.ExpandAll();
                }
                catch (Exception ex)
                {
                    traceLogger.Error(ex.StackTrace);
                }
            }
        }

        public delegate void LightChannelNameChanged(LightChanel lightChanel, string newName);
        public event LightChannelNameChanged LightChannelNameChangedEvent;
        #endregion

        /// <summary>
        /// 调试界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        //private void buttonitem_Debug_Click(object sender, EventArgs e)
        //{
        //    Frm_StationDebug debugForm = Frm_StationDebug.Instance;
        //    debugForm.Show();
        //}
    }
}
